/*
 * File:   Vector.h
 * Author: Elevator
 *
 * Created on 12 Май 2013 г., 15:41
 */

#ifndef COMMON_VECTOR_H
#define COMMON_VECTOR_H

#include <vector>
#include <iterator>
#include <algorithm>
#include "Common/Collections/IIterator.h"
#include "Common/Collections/IteratorPtr.h"

#include "Common/Collections/IIterable.h"
#include "Common/Collections/ICollection.h"
#include "Common/Collections/IVector.h"

#include "Common/Collections/VectorIterator.h"

template<typename T>
//class Vector : public IVector<C>//, public ICollection<C>, public IIterable<C>
class Vector : public IVector<T>
{
private:
	std::vector<T> _vector;

public:
	Vector(){}

	Vector(const IIterable<T>* source)	{
		for( IteratorPtr<T> sourceIter( source->GetIterator( ) );
			!sourceIter->IsEnd( );
			sourceIter->Next( ) )
		{
			_vector.push_back(sourceIter->Current());
		}
	}

	virtual IIterator<T>* GetIterator( ) const {
		return new VectorIterator<T> ( &_vector );
	}

	virtual int GetCount() const {
		return _vector.size();
	}

	virtual void Add( T item ) {
		_vector.push_back( item );
	}

	virtual void Remove( T item ) {
		_vector.erase(std::remove(_vector.begin(), _vector.end(), item), _vector.end());
	}

	virtual void Remove( bool (*predicate )( const T& item ) ) {
		_vector.erase(std::remove_if(_vector.begin(), _vector.end(), predicate), _vector.end());
	}

	virtual bool Contains( T item ) const {
		return std::find( _vector.begin( ), _vector.end( ), item ) != _vector.end( );
	}

	virtual void Clear() {
        _vector.clear();
	}

	virtual T operator[](int index) {
		return _vector[index];
	}

	virtual int IndexOf(T item) const {
		return (int)std::distance(_vector.begin(), std::find( _vector.begin( ), _vector.end( ), item ));
	}

	virtual void Insert(int index, T item) {
		_vector.insert(_vector.begin( ) + index, item);
	}


	virtual void RemoveAt(int index) {
		_vector.erase(_vector.begin( ) + index);
	}


	T Find( bool (*predicate )( const T& item ) ) {
		return *std::find_if( _vector.begin( ), _vector.end( ), predicate );
	}

	virtual std::vector<T> GetStdVector() const {
		std::vector<T> result;
		std::copy (_vector.begin(),_vector.end(),std::back_inserter(result));
		return result;
	}
};

#endif	/* VECTOR_H */

